package com.kexio.security.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.kexio.common.dto.Result;
import com.kexio.dynamic.config.service.ConfigService;
import com.kexio.dynamic.feature.annotation.FeatureToggle;
// import com.kexio.enterprise.observability.logging.annotation.OperateLog;
// import com.kexio.enterprise.governance.ratelimit.annotation.RateLimit;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;

/**
 * 动态配置管理控制器
 * 
 * @author kexio
 */
@RestController
@RequestMapping("/api/configs")
@Tag(name = "配置管理", description = "动态配置管理接口")
public class ConfigController {

    @Autowired
    private ConfigService configService;

    public ConfigController(ConfigService configService) {
        this.configService = configService;
    }

    /**
     * 获取配置值
     */
    @Operation(summary = "获取配置值", description = "根据配置键获取配置值")
    @GetMapping("/{key}")
    public ResponseEntity<Result<String>> getConfig(
            @Parameter(description = "配置键", required = true) @PathVariable String key) {
        
        try {
            String value = configService.getValue(key);
            if (value != null) {
                return ResponseEntity.ok(Result.success(value));
            } else {
                return ResponseEntity.ok(Result.error("配置不存在: " + key));
            }
        } catch (Exception e) {
            return ResponseEntity.ok(Result.error("获取配置失败: " + e.getMessage()));
        }
    }

    /**
     * 获取配置值（带默认值）
     */
    @Operation(summary = "获取配置值（带默认值）", description = "根据配置键获取配置值，如果不存在则返回默认值")
    @GetMapping("/{key}/default")
    public ResponseEntity<Result<String>> getConfigWithDefault(
            @Parameter(description = "配置键", required = true) @PathVariable String key,
            @RequestParam(defaultValue = "") String defaultValue) {
        
        try {
            String value = configService.getValue(key, defaultValue);
            return ResponseEntity.ok(Result.success(value));
        } catch (Exception e) {
            return ResponseEntity.ok(Result.error("获取配置失败: " + e.getMessage()));
        }
    }

    /**
     * 设置配置值
     */
    @Operation(summary = "设置配置值", description = "设置或更新配置值")
    // @RateLimit(key = "config_update", rate = 20, per = 60, description = "配置更新限流：每分钟20次")
    @FeatureToggle(value = "config_management", description = "配置管理功能",
                   onDisabled = FeatureToggle.DisabledStrategy.THROW_EXCEPTION,
                   disabledMessage = "配置管理功能暂时禁用")
    // @OperateLog(module = "配置管理", operation = "设置配置", type = OperateLog.OperationType.UPDATE,
    //            detail = "设置配置 #{key} = #{value}", businessKey = "#{key}")
    @PutMapping("/{key}")
    public ResponseEntity<Result<Boolean>> setConfig(
            @Parameter(description = "配置键", required = true) @PathVariable String key,
            @RequestBody String value) {
        
        try {
            boolean success = configService.updateValue(key, value);
            if (!success) {
                return ResponseEntity.ok(Result.error("设置配置失败"));
            }
            return ResponseEntity.ok(Result.success(true));
        } catch (Exception e) {
            return ResponseEntity.ok(Result.error("设置配置失败: " + e.getMessage()));
        }
    }

    /**
     * 删除配置
     */
    @Operation(summary = "删除配置", description = "删除指定的配置项")
    @FeatureToggle(value = "config_management", description = "配置管理功能")
    // @OperateLog(module = "配置管理", operation = "删除配置", type = OperateLog.OperationType.DELETE,
    //            detail = "删除配置: #{key}", businessKey = "#{key}")
    @DeleteMapping("/{key}")
    public ResponseEntity<Result<Boolean>> deleteConfig(
            @Parameter(description = "配置键", required = true) @PathVariable String key) {
        
        try {
            boolean deleted = configService.deleteConfig(key);
            return ResponseEntity.ok(Result.success(deleted));
        } catch (Exception e) {
            return ResponseEntity.ok(Result.error("删除配置失败: " + e.getMessage()));
        }
    }

    /**
     * 获取配置组
     */
    @Operation(summary = "获取配置组", description = "获取指定前缀的所有配置")
    @GetMapping("/group/{prefix}")
    public ResponseEntity<Result<Map<String, String>>> getConfigGroup(
            @Parameter(description = "配置前缀", required = true) @PathVariable String prefix) {
        
        try {
            Map<String, String> configs = configService.getGroupConfigs(prefix);
            return ResponseEntity.ok(Result.success(configs));
        } catch (Exception e) {
            return ResponseEntity.ok(Result.error("获取配置组失败: " + e.getMessage()));
        }
    }

    /**
     * 批量设置配置
     */
    @Operation(summary = "批量设置配置", description = "批量设置多个配置项")
    @FeatureToggle(value = "batch_config_operations", description = "批量配置操作功能")
    // @OperateLog(module = "配置管理", operation = "批量设置配置", type = OperateLog.OperationType.UPDATE,
    //            detail = "批量设置配置，数量: #{configs.size()}")
    @PostMapping("/batch")
    public ResponseEntity<Result<Boolean>> batchSetConfigs(
            @RequestBody Map<String, String> configs) {
        
        try {
            for (Map.Entry<String, String> entry : configs.entrySet()) {
                configService.updateValue(entry.getKey(), entry.getValue());
            }
            return ResponseEntity.ok(Result.success("批量设置配置成功", true));
        } catch (Exception e) {
            return ResponseEntity.ok(Result.error("批量设置配置失败: " + e.getMessage()));
        }
    }

    /**
     * 获取所有配置键
     */
    @Operation(summary = "获取所有配置键", description = "获取系统中所有的配置键")
    @GetMapping("/keys")
    public ResponseEntity<Result<List<String>>> getAllConfigKeys() {
        
        try {
            List<String> keys = configService.getAllConfigs().stream()
                    .map(config -> config.getConfigKey())
                    .collect(java.util.stream.Collectors.toList());
            return ResponseEntity.ok(Result.success(keys));
        } catch (Exception e) {
            return ResponseEntity.ok(Result.error("获取配置键失败: " + e.getMessage()));
        }
    }

    /**
     * 刷新配置缓存
     */
    @Operation(summary = "刷新配置缓存", description = "刷新动态配置缓存")
    @FeatureToggle(value = "config_cache_management", description = "配置缓存管理功能")
    // @OperateLog(module = "配置管理", operation = "刷新配置缓存", type = OperateLog.OperationType.UPDATE,
    //            detail = "刷新配置缓存")
    @PostMapping("/refresh")
    public ResponseEntity<Result<Boolean>> refreshConfigCache() {
        
        try {
            configService.refreshCache();
            return ResponseEntity.ok(Result.success("配置缓存刷新成功", true));
        } catch (Exception e) {
            return ResponseEntity.ok(Result.error("配置缓存刷新失败: " + e.getMessage()));
        }
    }

    /**
     * 获取配置变更历史
     */
    @Operation(summary = "获取配置变更历史", description = "获取指定配置的变更历史")
    @GetMapping("/{key}/history")
    public ResponseEntity<Result<List<Object>>> getConfigHistory(
            @Parameter(description = "配置键", required = true) @PathVariable String key,
            @RequestParam(defaultValue = "10") int limit) {
        
        try {
            // 这里应该从配置变更历史表获取数据
            List<Object> history = new java.util.ArrayList<>();
            return ResponseEntity.ok(Result.success("暂无配置变更历史", history));
        } catch (Exception e) {
            return ResponseEntity.ok(Result.error("获取配置历史失败: " + e.getMessage()));
        }
    }
}
